package com.mindskip.xzs.service.impl;

import com.mindskip.xzs.domain.*;
import com.mindskip.xzs.domain.enums.ExamPaperTypeEnum;
import com.mindskip.xzs.domain.exam.ExamPaperTitleItemObject;
import com.mindskip.xzs.domain.exam.QuestionTestStateEnum;
import com.mindskip.xzs.event.CalculateExamPaperAnswerCompleteEvent;
import com.mindskip.xzs.repository.ExamPaperMapper;
import com.mindskip.xzs.repository.QuestionMapper;
import com.mindskip.xzs.repository.QuestionTestRepository;
import com.mindskip.xzs.service.*;
import com.mindskip.xzs.utility.*;
import com.mindskip.xzs.viewmodel.admin.exam.ExamPaperEditRequestVM;
import com.mindskip.xzs.viewmodel.admin.exam.ExamPaperTitleItemVM;
import com.mindskip.xzs.viewmodel.admin.question.QuestionEditRequestVM;
import com.mindskip.xzs.viewmodel.student.exam.ExamPaperSubmitItemVM;
import com.mindskip.xzs.viewmodel.student.exam.ExamPaperSubmitVM;
import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class ExamRandomServiceImpl implements ExamRandomService {

    protected final static ModelMapper modelMapper = ModelMapperSingle.Instance();
    private final ExamPaperMapper examPaperMapper;
    private final QuestionMapper questionMapper;
    private final TextContentService textContentService;
    private final QuestionService questionService;
    private final QuestionTestRepository questionTestRepository;
    private final ApplicationEventPublisher eventPublisher;
    private final ExamPaperService examPaperService;


    @Autowired
    public ExamRandomServiceImpl(ExamPaperMapper examPaperMapper, QuestionMapper questionMapper, TextContentService textContentService, QuestionService questionService, QuestionTestRepository questionTestRepository, ApplicationEventPublisher eventPublisher, ExamPaperService examPaperService) {
        this.examPaperMapper = examPaperMapper;
        this.questionMapper = questionMapper;
        this.textContentService = textContentService;
        this.questionService = questionService;
        this.questionTestRepository = questionTestRepository;
        this.eventPublisher = eventPublisher;
        this.examPaperService = examPaperService;
    }


    @Override
    public ExamPaperEditRequestVM getNextQuestion(User user, ExamPaperSubmitVM examPaperSubmitVM) {

        QuestionTestData questionTestData = QuestionTestUtil.cache.get(user.getId());
        if (null == questionTestData) {
            questionTestData = new QuestionTestData();
            questionTestData.setState(QuestionTestStateEnum.TESTING);
            QuestionTestUtil.cache.put(user.getId(), questionTestData);
        }

        // 判断最后一道题是否正确
        boolean correctFromVM;
        List<ExamPaperSubmitItemVM> answerItems = examPaperSubmitVM.getAnswerItems();
        System.out.println("examPaperSubmitVM.getAnswerItems()----" + JsonUtil.toJsonStr(examPaperSubmitVM.getAnswerItems()));
        if (answerItems.size() > 0) {

            // 拿到答案
            ExamPaperSubmitItemVM examPaperSubmitItemVM = answerItems.get(0);
            // 拿到缓存的问题
            Question lastQuestion = questionTestData.getHistoryTestList().get(examPaperSubmitItemVM.getQuestionId());
            correctFromVM = ExamUtil.isCorrectFromVM(lastQuestion, examPaperSubmitItemVM);
            examPaperSubmitItemVM.setDoRight(correctFromVM);
            examPaperSubmitItemVM.setScore(String.valueOf(lastQuestion.getScore()));
            // 答案留档
            questionTestData.getAnswer().add(examPaperSubmitItemVM);
            List<ExamPaperSubmitItemVM> answer = questionTestData.getAnswer();

            StringBuilder sb = new StringBuilder();
            for (ExamPaperSubmitItemVM paperSubmitItemVM : answer) {
                sb.append(paperSubmitItemVM + " ==== ");
            }
            System.out.println("每一道题输出时答案list----" + JsonUtil.toJsonStr(answer));
            System.out.println("存答案的path" + sb.toString());
        }

        // 考试结束
        if (questionTestData.getAnswer().size() == QuestionTestUtil.getTestSize()) {
            return getEndData(questionTestData, user);
        }


        // 固定使用一个试卷
        ExamPaper examPaper = examPaperMapper.selectByPrimaryKey(1);
        ExamPaperEditRequestVM vm = modelMapper.map(examPaper, ExamPaperEditRequestVM.class);
        vm.setLevel(examPaper.getGradeLevel());
        TextContent frameTextContent = textContentService.selectById(examPaper.getFrameTextContentId());
        List<ExamPaperTitleItemObject> examPaperTitleItemObjects = JsonUtil.toJsonListObject(frameTextContent.getContent(), ExamPaperTitleItemObject.class);

        // 生成一条题目
        LinkedHashMap<Integer, Question> historyTestList = questionTestData.getHistoryTestList();
        Question randomQuestion = questionTestRepository.selectRandom(historyTestList.keySet());

        if (null == randomQuestion) {
            return getEndData(questionTestData, user);
        }
        // 缓存保存问题
        questionTestData.getHistoryTestList().put(randomQuestion.getId(), randomQuestion);

        // 生成的题目id fill the view model
        examPaperTitleItemObjects.get(0).getQuestionItems().get(0).setId(randomQuestion.getId());
        List<Integer> questionIds = examPaperTitleItemObjects.stream()
                .flatMap(t -> t.getQuestionItems().stream()
                        .map(q -> q.getId()))
                .collect(Collectors.toList());
        List<Question> questions = questionMapper.selectByIds(questionIds);
        List<ExamPaperTitleItemVM> examPaperTitleItemVMS = examPaperTitleItemObjects.stream().map(t -> {
            ExamPaperTitleItemVM tTitleVM = modelMapper.map(t, ExamPaperTitleItemVM.class);
            List<QuestionEditRequestVM> questionItemsVM = t.getQuestionItems().stream().map(i -> {
                Question question = questions.stream().filter(q -> q.getId().equals(i.getId())).findFirst().get();
                QuestionEditRequestVM questionEditRequestVM = questionService.getQuestionEditRequestVM(question);
                questionEditRequestVM.setItemOrder(i.getItemOrder());
                return questionEditRequestVM;
            }).collect(Collectors.toList());
            tTitleVM.setQuestionItems(questionItemsVM);
            return tTitleVM;
        }).collect(Collectors.toList());
        vm.setTitleItems(examPaperTitleItemVMS);
        vm.setScore(ExamUtil.scoreToVM(examPaper.getScore()));
        if (ExamPaperTypeEnum.TimeLimit == ExamPaperTypeEnum.fromCode(examPaper.getPaperType())) {
            List<String> limitDateTime = Arrays.asList(DateTimeUtil.dateFormat(examPaper.getLimitStartTime()), DateTimeUtil.dateFormat(examPaper.getLimitEndTime()));
            vm.setLimitDateTime(limitDateTime);
        }
        vm.setState(1);

        // 保存titleItem
        questionTestData.getTitleItems().addAll(examPaperTitleItemVMS);


        return vm;
    }

    private ExamPaperEditRequestVM getEndData(QuestionTestData questionTestData, User user) {

        ExamPaperEditRequestVM vm;
        vm = new ExamPaperEditRequestVM();
        vm.setState(2);
        int score = 0;
        for (ExamPaperSubmitItemVM examPaperSubmitItemVM : questionTestData.getAnswer()) {
            if (examPaperSubmitItemVM.getDoRight()) {
                score += Integer.parseInt(examPaperSubmitItemVM.getScore());
            }
        }
        vm.setScore(String.valueOf(score));

        List<ExamPaperSubmitItemVM> answer = questionTestData.getAnswer();
        System.out.println("end data----" + JsonUtil.toJsonStr(answer));


        // 构造随机试卷
        ExamPaperEditRequestVM newExamPaper = new ExamPaperEditRequestVM();
        newExamPaper.setTitleItems(questionTestData.getTitleItems());
        newExamPaper.setLevel(1);
        newExamPaper.setSubjectId(1);
        newExamPaper.setPaperType(1);
        newExamPaper.setName("随机测试");
        newExamPaper.setSuggestTime(60);
        newExamPaper.setTemp(true);

        ExamPaper examPaper = examPaperService.savePaperFromVM(newExamPaper, user);


        // 构造考试记录
        ExamPaperAnswerInfo examPaperAnswerInfo = new ExamPaperAnswerInfo();
        Date now = new Date();

        String frameTextContent = textContentService.selectById(examPaper.getFrameTextContentId()).getContent();
        List<ExamPaperTitleItemObject> examPaperTitleItemObjects = JsonUtil.toJsonListObject(frameTextContent, ExamPaperTitleItemObject.class);
        List<Integer> questionIds = examPaperTitleItemObjects.stream().flatMap(t -> t.getQuestionItems().stream().map(q -> q.getId())).collect(Collectors.toList());
        List<Question> questions = questionMapper.selectByIds(questionIds);
        List<ExamPaperSubmitItemVM> copyAnswerItems = new ArrayList<>(questionTestData.getAnswer());
        //将题目结构的转化为题目答案
        List<ExamPaperQuestionCustomerAnswer> examPaperQuestionCustomerAnswers = examPaperTitleItemObjects.stream()
                .flatMap(t -> t.getQuestionItems().stream()
                        .map(q -> {
                            Question question = questions.stream().filter(tq -> tq.getId().equals(q.getId())).findFirst().get();

                            Iterator<ExamPaperSubmitItemVM> answerIt = copyAnswerItems.iterator();
                            while (answerIt.hasNext()) {
                                ExamPaperSubmitItemVM customerQuestionAnswer = answerIt.next();
                                if (!customerQuestionAnswer.getQuestionId().equals(q.getId())) {
                                    continue;
                                }
                                answerIt.remove();
                                return ExamPaperAnswerServiceImpl.ExamPaperQuestionCustomerAnswerFromVM(question, customerQuestionAnswer, examPaper, q.getItemOrder(), user, now);
                            }

                            return null;
                        })
                ).collect(Collectors.toList());

        ExamPaperSubmitVM build = ExamPaperSubmitVM.builder().doTime(100).build();
        ExamPaperAnswer examPaperAnswer = ExamPaperAnswerServiceImpl.ExamPaperAnswerFromVM(build, examPaper, examPaperQuestionCustomerAnswers, user, now);
        examPaperAnswerInfo.setExamPaper(examPaper);
        examPaperAnswerInfo.setExamPaperAnswer(examPaperAnswer);
        examPaperAnswerInfo.setExamPaperQuestionCustomerAnswers(examPaperQuestionCustomerAnswers);
        // 推送考试记录
        eventPublisher.publishEvent(new CalculateExamPaperAnswerCompleteEvent(examPaperAnswerInfo));

        // 清空userid缓存
        QuestionTestUtil.cache.remove(user.getId());
        return vm;
    }

}
